package com.toolbox.utils;

import org.apache.commons.imaging.Imaging;
import org.apache.commons.imaging.common.ImageMetadata;
import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;
import org.apache.commons.imaging.formats.jpeg.exif.ExifRewriter;
import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
import org.apache.commons.imaging.formats.tiff.write.TiffOutputSet;

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.*;
import java.nio.file.Files;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;

/**
 * 标准证件照换红底工具 - 专为人物照片优化
 */
public class CommonsImagingBackgroundChanger {
    
    /**
     * 获取标准证件照红色背景颜色
     */
    private static Color getStandardRedColor() {
        return new Color(255, 20, 60); // 标准证件照红色背景 (柔和的红色，符合证件照规范)
    }

    /**
     * 将照片背景更换为红色标准证件照背景
     * 
     * @param imageBytes 图像字节数组
     * @return 处理后的图像字节数组
     */
    public static byte[] changeToRedBackground(byte[] imageBytes) {
        return changeToRedBackground(imageBytes, 800, true);
    }
    
    /**
     * 兼容性方法 - 保持与前端的向后兼容
     * 
     * @param imageBytes 图像字节数组
     * @param targetBackground 目标背景色（已忽略，始终使用红色）
     * @return 处理后的图像字节数组
     */
    public static byte[] changePhotoBackground(byte[] imageBytes, String targetBackground) {
        // 忽略targetBackground参数，始终使用红色背景
        return changeToRedBackground(imageBytes, 800, true);
    }
    
    /**
     * 将人物照片转换为标准红底证件照（增强版）
     * @param imageBytes 原始图像字节数组
     * @param maxDimension 最大尺寸
     * @param enhanceFace 是否增强面部效果
     * @return 处理后的红底证件照字节数组
     */
    public static byte[] changeToRedBackground(byte[] imageBytes, int maxDimension, boolean enhanceFace) {
        // 直接设置为红色背景，专注于红底证件照处理
        String targetBackground = "red";
        try {
            // 1. Read original image
            System.out.println("Step 1: Reading original image");
            BufferedImage sourceImage = Imaging.getBufferedImage(imageBytes);
            ImageMetadata metadata = Imaging.getMetadata(imageBytes);
            int width = sourceImage.getWidth();
            int height = sourceImage.getHeight();
            System.out.println("Original image size: " + width + "x" + height);

            // 2. Calculate scale factor to resize large images
            System.out.println("Step 2: Calculating scale factor for ID photo");
            double scaleFactor = 1.0;
            BufferedImage resizedImage = sourceImage;
            
            if (width > maxDimension || height > maxDimension) {
                scaleFactor = (double) maxDimension / Math.max(width, height);
                int newWidth = (int)(width * scaleFactor);
                int newHeight = (int)(height * scaleFactor);
                System.out.println("Resizing image for ID photo: " + newWidth + "x" + newHeight);
                resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
                Graphics2D g2d = resizedImage.createGraphics();
                g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                g2d.drawImage(sourceImage, 0, 0, newWidth, newHeight, null);
                g2d.dispose();
            }
            
            // 3. Create new target image
            System.out.println("Step 3: Creating target image");
            BufferedImage resultImage = new BufferedImage(
                    width, height, BufferedImage.TYPE_INT_RGB
            );
            
            // 4. 设置标准证件照红色背景
            System.out.println("Step 4: Setting red background");
            Color backgroundColor = getStandardRedColor();
            Graphics2D graphics = resultImage.createGraphics();
            
            // Set rendering quality
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            
            // 5. Fill background with color or gradient image
            System.out.println("Step 5: Filling background");
            if ("blue".equalsIgnoreCase(targetBackground) || "red".equalsIgnoreCase(targetBackground)) {
                // 对于蓝色和红色背景，使用渐变背景图
                BufferedImage gradientBg = loadGradientBackground(width, height, targetBackground);
                if (gradientBg != null) {
                    graphics.drawImage(gradientBg, 0, 0, width, height, null);
                } else {
                    // 如果无法加载渐变背景，使用纯色背景作为备选
                    System.out.println("Failed to load gradient background, using solid color instead");
                    graphics.setColor(backgroundColor);
                    graphics.fillRect(0, 0, width, height);
                }
            } else {
                // 其他背景色使用纯色
                graphics.setColor(backgroundColor);
                graphics.fillRect(0, 0, width, height);
            }
            
            // 6. Perform background replacement using optimized image
            System.out.println("Step 6: Performing background replacement");
            BufferedImage processedImage = performBackgroundReplacement(resizedImage, backgroundColor);
            System.out.println("Background replacement completed");
            
            // 7. Draw processed image to target image (restore original size)
            System.out.println("Step 7: Drawing processed image");
            graphics.drawImage(processedImage, 0, 0, width, height, null);
            graphics.dispose();
            
            // 8. Apply image enhancement with ID photo optimization
            System.out.println("Step 8: Applying image enhancement for ID photo");
            resultImage = enhanceImageQualityOptimized(resultImage, enhanceFace);
            System.out.println("ID photo enhancement completed");
            
            // 9. Write result to byte array using ImageIO
            System.out.println("Step 9: Writing image data");
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            
            // Write image using standard ImageIO
            ImageIO.write(resultImage, "jpg", outputStream);
            outputStream.flush();
            System.out.println("Image writing completed, output size: " + outputStream.size() + " bytes");
            
            // 10. 尝试保留原始图像的Exif元数据
            try {
                if (metadata instanceof JpegImageMetadata) {
                    JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata;
                    TiffImageMetadata exif = jpegMetadata.getExif();
                    
                    if (exif != null) {
                        // 保留原始Exif数据
                        TiffOutputSet outputSet = exif.getOutputSet();
                        if (outputSet != null) {
                            // 创建临时文件来处理Exif数据
                            File tempInputFile = File.createTempFile("input_", ".jpg");
                            File tempOutputFile = File.createTempFile("output_", ".jpg");
                            
                            try {
                                // 写入临时文件
                                Files.write(tempInputFile.toPath(), outputStream.toByteArray());
                                
                                // 使用ExifRewriter保留元数据
                                new ExifRewriter().updateExifMetadataLossless(
                                        new FileInputStream(tempInputFile),
                                        new FileOutputStream(tempOutputFile),
                                        outputSet
                                );
                                
                                // 读取带有原始元数据的结果
                                return Files.readAllBytes(tempOutputFile.toPath());
                            } finally {
                                // 清理临时文件
                                tempInputFile.delete();
                                tempOutputFile.delete();
                            }
                        }
                    }
                }
            } catch (Exception e) {
                // Ignore metadata processing errors, return image without metadata
                System.err.println("Failed to preserve image metadata: " + e.getMessage());
            }
            
            return outputStream.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("Image processing failed: " + e.getMessage(), e);
        }
    }
    
    /**
     * 加载渐变背景图
     */
    private static BufferedImage loadGradientBackground(int width, int height, String backgroundType) {
        try {
            // 根据背景类型获取对应的SVG背景文件路径
            String svgPath;
            if ("red".equalsIgnoreCase(backgroundType)) {
                svgPath = "/backgrounds/red_gradient_background.svg";
            } else {
                svgPath = "/backgrounds/blue_gradient_background.svg";
            }
            
            System.out.println("Attempting to load gradient background from: " + svgPath);
            
            // 尝试使用ClassLoader获取资源
            InputStream svgStream = ClassLoader.getSystemResourceAsStream(svgPath.substring(1)); // 去掉开头的斜杠
            
            if (svgStream == null) {
                // 如果ClassLoader方法失败，尝试使用类的getResourceAsStream方法
                svgStream = CommonsImagingBackgroundChanger.class.getResourceAsStream(svgPath);
            }
            
            if (svgStream == null) {
                System.err.println("Gradient background SVG file not found at: " + svgPath);
                return null;
            }
            
            // 使用Batik库将SVG转换为BufferedImage
            PNGTranscoder transcoder = new PNGTranscoder();
            transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, (float) width);
            transcoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, (float) height);
            
            // 设置输入和输出
            TranscoderInput input = new TranscoderInput(svgStream);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            TranscoderOutput output = new TranscoderOutput(outputStream);
            
            // 执行转换
            transcoder.transcode(input, output);
            outputStream.flush();
            
            // 将输出流转换为BufferedImage
            byte[] pngData = outputStream.toByteArray();
            System.out.println("Successfully loaded and converted gradient background: " + backgroundType);
            return ImageIO.read(new ByteArrayInputStream(pngData));
        } catch (IOException | TranscoderException e) {
            System.err.println("Failed to load gradient background: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 执行背景替换操作 - 增强版
     */
    private static BufferedImage performBackgroundReplacement(BufferedImage image, Color backgroundColor) {
        int width = image.getWidth();
        int height = image.getHeight();
        
        // 创建结果图像
        BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        
        // 填充背景色
        Graphics2D g2d = result.createGraphics();
        g2d.setColor(backgroundColor);
        g2d.fillRect(0, 0, width, height);
        g2d.dispose();
        
        // 扫描图像，识别前景和背景
        int totalPixels = width * height;
        int foregroundPixels = 0;
        int backgroundPixels = 0;
        
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                int rgb = image.getRGB(x, y);
                int r = (rgb >> 16) & 0xFF;
                int g = (rgb >> 8) & 0xFF;
                int b = rgb & 0xFF;
                
                // 判断是否为背景像素 - 使用改进的判断条件
                boolean isBg = isBackgroundPixel(rgb, backgroundColor);
                
                if (!isBg) {
                    // 非背景像素 - 检查是否为边缘
                    boolean isEdge = isEdgePixel(image, x, y, backgroundColor);
                    
                    if (isEdge) {
                        // 边缘像素进行平滑处理
                        result.setRGB(x, y, getEnhancedSmoothedPixel(image, x, y, backgroundColor));
                    } else {
                        // 非边缘前景像素直接保留
                        result.setRGB(x, y, rgb);
                    }
                    foregroundPixels++;
                } else {
                    // 背景像素保持背景色不变
                    backgroundPixels++;
                }
            }
        }
        
        System.out.println("Background replacement stats: foreground pixels=" + foregroundPixels + ", background pixels=" + backgroundPixels + ", total=" + totalPixels);
        
        return result;
    }
    
    /**
     * 判断是否为边缘像素
     */
    private static boolean isEdgePixel(BufferedImage image, int x, int y, Color backgroundColor) {
        int width = image.getWidth();
        int height = image.getHeight();
        
        // 检查周围8个像素
        for (int dy = -1; dy <= 1; dy++) {
            for (int dx = -1; dx <= 1; dx++) {
                if (dx == 0 && dy == 0) continue; // 跳过当前像素
                
                int nx = x + dx;
                int ny = y + dy;
                
                // 检查边界
                if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
                    int neighborRGB = image.getRGB(nx, ny);
                    if (isBackgroundPixel(neighborRGB, backgroundColor)) {
                        return true; // 周围有背景像素，当前像素是边缘
                    }
                }
            }
        }
        
        return false;
    }
    
    /**
     * 对边缘像素进行增强的平滑处理
     */
    private static int getEnhancedSmoothedPixel(BufferedImage image, int x, int y, Color backgroundColor) {
        int width = image.getWidth();
        int height = image.getHeight();
        
        int r = 0, g = 0, b = 0;
        double totalWeight = 0;
        
        // 获取当前像素的RGB值
        int currentRGB = image.getRGB(x, y);
        int currR = (currentRGB >> 16) & 0xFF;
        int currG = (currentRGB >> 8) & 0xFF;
        int currB = currentRGB & 0xFF;
        
        // 扩大采样范围到7x7，提高边缘平滑效果
        for (int dy = -3; dy <= 3; dy++) {
            for (int dx = -3; dx <= 3; dx++) {
                int nx = x + dx;
                int ny = y + dy;
                
                if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
                    int neighborRGB = image.getRGB(nx, ny);
                    if (!isBackgroundPixel(neighborRGB, backgroundColor)) {
                        // 计算距离（避免除零）
                        double distance = Math.sqrt(dx*dx + dy*dy) + 0.1;
                        // 平方倒数加权，更强调近邻像素
                        double weight = 1.0 / (distance * distance);
                        
                        // 额外的肤色保护加权 - 对于红底照片特别重要
                        if (isSkinPixel(neighborRGB)) {
                            weight *= 1.5; // 增加肤色像素的权重
                        }
                        
                        r += (int)(((neighborRGB >> 16) & 0xFF) * weight);
                        g += (int)(((neighborRGB >> 8) & 0xFF) * weight);
                        b += (int)((neighborRGB & 0xFF) * weight);
                        totalWeight += weight;
                    }
                }
            }
        }
        
        // 如果没有找到非背景像素，返回原像素
        if (totalWeight == 0) {
            return currentRGB;
        }
        
        // 计算加权平均值
        r = (int)(r / totalWeight);
        g = (int)(g / totalWeight);
        b = (int)(b / totalWeight);
        
        // 混合部分背景色，使边缘更自然
        int bgR = backgroundColor.getRed();
        int bgG = backgroundColor.getGreen();
        int bgB = backgroundColor.getBlue();
        
        // 计算边缘强度和距离背景的远近
        int edgeStrength = 0;
        double minBgDistance = Double.MAX_VALUE;
        
        for (int dy = -2; dy <= 2; dy++) {
            for (int dx = -2; dx <= 2; dx++) {
                if (dx == 0 && dy == 0) continue;
                
                int nx = x + dx;
                int ny = y + dy;
                if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
                    int neighborRGB = image.getRGB(nx, ny);
                    if (isBackgroundPixel(neighborRGB, backgroundColor)) {
                        edgeStrength++;
                        // 计算到背景像素的距离
                        double distance = Math.sqrt(dx*dx + dy*dy);
                        if (distance < minBgDistance) {
                            minBgDistance = distance;
                        }
                    }
                }
            }
        }
        
        // 根据边缘强度和距离背景的远近调整混合比例
        double distanceFactor = Math.max(0.1, 1.0 - minBgDistance / 4.0); // 距离越近，混合越多
        double alpha = Math.min(0.6, edgeStrength > 0 ? Math.min(0.6, edgeStrength * 0.15 * distanceFactor) : 0); // 混合因子
        
        // 智能混合 - 对于红色背景特别优化
        if (backgroundColor.equals(new Color(255, 20, 60))) {
            // 降低红色通道的混合比例，防止人物边缘泛红
            double redAlpha = alpha * 0.6; // 红色通道混合60%
            double otherAlpha = alpha; // 绿色通道和蓝色通道正常混合
            
            r = (int)(r * (1 - redAlpha) + bgR * redAlpha);
            g = (int)(g * (1 - otherAlpha) + bgG * otherAlpha);
            b = (int)(b * (1 - otherAlpha) + bgB * otherAlpha);
        } else {
            // 普通混合
            r = (int)(r * (1 - alpha) + bgR * alpha);
            g = (int)(g * (1 - alpha) + bgG * alpha);
            b = (int)(b * (1 - alpha) + bgB * alpha);
        }
        
        // 智能锐化 - 根据边缘特性调整锐化程度
        if (edgeStrength > 0 && edgeStrength < 5) { // 弱边缘
            // 轻微锐化
            r = Math.min(255, Math.max(0, (int)(r * 1.03)));
            g = Math.min(255, Math.max(0, (int)(g * 1.03)));
            b = Math.min(255, Math.max(0, (int)(b * 1.03)));
        }
        
        return (r << 16) | (g << 8) | b;
    }
    
    /**
     * 判断像素是否为背景像素 - 增强版
     */
    private static boolean isBackgroundPixel(int rgb, Color backgroundColor) {
        int r = (rgb >> 16) & 0xFF;
        int g = (rgb >> 8) & 0xFF;
        int b = rgb & 0xFF;
        
        // 背景色的RGB值
        int bgR = backgroundColor.getRed();
        int bgG = backgroundColor.getGreen();
        int bgB = backgroundColor.getBlue();
        
        // 计算与背景色的欧氏距离
        double distance = Math.sqrt(Math.pow(r - bgR, 2) + Math.pow(g - bgG, 2) + Math.pow(b - bgB, 2));
        
        // 动态阈值，根据目标背景色调整
        if (backgroundColor.equals(Color.WHITE)) {
            // 白色背景使用亮度阈值
            int brightness = (int)(0.299 * r + 0.587 * g + 0.114 * b);
            return brightness > 200 && distance < 60;
        } else if (backgroundColor.equals(new Color(255, 20, 60))) {
            // 红色背景 - 高级色彩识别算法（优化版）
            // 转换到HSV色彩空间进行更精确的红色识别
            float[] hsv = new float[3];
            Color.RGBtoHSB(r, g, b, hsv);
            float hue = hsv[0];
            float saturation = hsv[1];
            float value = hsv[2];
            
            // 红色在HSV空间中的范围通常是0-15度或345-360度
            boolean isRedHue = (hue >= 0 && hue <= 0.04) || (hue >= 0.96 && hue <= 1.0);
            boolean isSaturated = saturation > 0.4; // 提高饱和度阈值，减少误判
            boolean isBrightEnough = value > 0.3; // 提高亮度阈值
            
            // 综合RGB和HSV的判断条件
            boolean isRedBased = r > 120 && r > g && r > b && (r - g) > 30 && (r - b) > 30;
            boolean hasRedTone = r > 150 && (r - g) > 40 && (r - b) > 40;
            boolean isCloseToTargetRed = distance < 100; // 缩小距离阈值，更精确匹配目标红色
            
            // 防止将肤色误判为红色背景
            boolean isSkinColor = isSkinPixel(rgb);
            if (isSkinColor) {
                return false;
            }
            
            // 针对不同光照条件的自适应判断
            if (value > 0.7) { // 高光区域
                return (isRedHue && isSaturated && isBrightEnough) && isCloseToTargetRed;
            } else if (value < 0.3) { // 阴影区域
                return isRedBased && (r > 100) && (distance < 80);
            } else { // 中间调区域
                return (isRedHue && isSaturated && isBrightEnough) && (hasRedTone || isCloseToTargetRed);
            }
        } else if (backgroundColor.equals(new Color(67, 142, 219))) {
            // 蓝色背景 - 更灵活的判断条件
            boolean isBlueBased = r < 130 && g < 190 && b > 170;
            boolean hasBlueDominance = Math.abs(b - r) > 40 && Math.abs(b - g) > 20;
            boolean withinColorRange = distance < 100;
            
            return isBlueBased && hasBlueDominance && withinColorRange;
        } else {
            // 其他背景色使用更大的距离阈值，提高兼容性
            return distance < 90;
        }
    }
    
    /**
     * 判断是否为肤色像素
     */
    private static boolean isSkinPixel(int rgb) {
        int r = (rgb >> 16) & 0xFF;
        int g = (rgb >> 8) & 0xFF;
        int b = rgb & 0xFF;
        
        // YCrCb色彩空间中的肤色检测
        int y = (int)(0.299 * r + 0.587 * g + 0.114 * b);
        int cr = (int)(r - y + 128);
        int cb = (int)(b - y + 128);
        
        // HSV色彩空间中的肤色检测
        float hsv[] = new float[3];
        Color.RGBtoHSB(r, g, b, hsv);
        float hue = hsv[0];
        float saturation = hsv[1];
        float value = hsv[2];
        
        // 综合多个条件判断肤色
        boolean isSkinYCrCb = (cr >= 133 && cr <= 173 && cb >= 77 && cb <= 127);
        boolean isSkinHSV = (hue >= 0 && hue <= 0.2 && saturation >= 0.2 && saturation <= 0.6 && value >= 0.4);
        boolean isSkinRGB = (r > g && g > b && r > 95 && g > 40 && b > 20 && 
                            (Math.max(r, Math.max(g, b)) - Math.min(r, Math.min(g, b))) > 15);
        
        // 综合多个肤色检测算法的结果
        return isSkinYCrCb || isSkinHSV || isSkinRGB;
    }
    
    /**
     * 优化的图像增强方法 - 支持证件照面部优化
     */
    private static BufferedImage enhanceImageQualityOptimized(BufferedImage image, boolean enhanceFace) {
        int width = image.getWidth();
        int height = image.getHeight();
        
        // 创建目标图像
        BufferedImage destination = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        
        // 先复制原图到目标图像
        Graphics2D g2d = destination.createGraphics();
        g2d.drawImage(image, 0, 0, null);
        g2d.dispose();
        
        // 先应用颜色平衡调整，这样颜色优化的效果会更明显
        adjustColorBalanceOptimized(destination, enhanceFace);
        
        // 简化的对比度增强，降低系数避免过度增强
        BufferedImage finalResult = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                // 跳过边界像素
                if (x > 0 && x < width - 1 && y > 0 && y < height - 1) {
                    int rgb = destination.getRGB(x, y);
                    int r = (rgb >> 16) & 0xFF;
                    int g = (rgb >> 8) & 0xFF;
                    int b = rgb & 0xFF;
                    
                    // 降低对比度增强系数，避免过度增强红色
                    float contrastFactor = 1.1f;
                    
                    r = (int)(128 + (r - 128) * contrastFactor);
                    g = (int)(128 + (g - 128) * contrastFactor);
                    b = (int)(128 + (b - 128) * contrastFactor);
                    
                    // 边界检查
                    r = Math.min(255, Math.max(0, r));
                    g = Math.min(255, Math.max(0, g));
                    b = Math.min(255, Math.max(0, b));
                    
                    finalResult.setRGB(x, y, (r << 16) | (g << 8) | b);
                } else {
                    // 边界像素直接复制
                    finalResult.setRGB(x, y, destination.getRGB(x, y));
                }
            }
        }
        
        return finalResult;
    }
    
    /**
     * 优化的颜色平衡调整 - 证件照专用
     */
    private static void adjustColorBalanceOptimized(BufferedImage image, boolean enhanceFace) {
        int width = image.getWidth();
        int height = image.getHeight();
        
        // 定义标准证件照红色背景RGB值
        Color redBackground = new Color(255, 20, 60);
        
        for (int y = 0; y < height; y += 1) {
            for (int x = 0; x < width; x += 1) {
                int rgb = image.getRGB(x, y);
                int r = (rgb >> 16) & 0xFF;
                int g = (rgb >> 8) & 0xFF;
                int b = rgb & 0xFF;
                
                // 检查是否是红色背景像素 - 更适合渐变背景的检测
                boolean isRedBackgroundPixel = r > 150 && g < 150 && b < 150 && 
                                              (r - g) > 40 && (r - b) > 40;
                
                if (isRedBackgroundPixel) {
                    // 优化红色背景 - 确保符合证件照标准
                    r = Math.min(255, (int)(r * 1.08)); // 增强红色饱和度，使其更符合证件照要求
                    g = Math.max(20, Math.min(70, g));   // 严格控制绿色分量，避免偏色
                    b = Math.max(0, Math.min(50, b));    // 严格控制蓝色分量，确保红色纯正
                } else if (isSkinPixelFast(r, g, b) && enhanceFace) {
                    // 肤色区域优化 - 证件照面部增强
                    // 美白和平衡肤色，同时保持自然效果
                    r = Math.min(240, Math.max(0, (int)(r * 1.02))); // 略微增强红色分量，提升气色
                    g = Math.min(255, Math.max(0, (int)(g * 1.06))); // 增强绿色分量，平衡肤色
                    b = Math.min(255, Math.max(0, (int)(b * 1.10))); // 增强蓝色分量，提亮肤色
                    
                    // 智能磨皮效果 - 平滑肤色但保留细节
                    int smoothFactor = 5; // 平滑系数
                    r = Math.min(255, Math.max(0, (int)(r + (128 - r) / smoothFactor)));
                    g = Math.min(255, Math.max(0, (int)(g + (128 - g) / smoothFactor)));
                    b = Math.min(255, Math.max(0, (int)(b + (128 - b) / smoothFactor)));
                } else {
                    // 非肤色非背景区域增强对比度，使照片更清晰
                    r = (int)(r * 1.08);
                    g = (int)(g * 1.05);
                    b = (int)(b * 1.05);
                }
                
                // 边界检查
                r = Math.min(255, Math.max(0, r));
                g = Math.min(255, Math.max(0, g));
                b = Math.min(255, Math.max(0, b));
                
                image.setRGB(x, y, (r << 16) | (g << 8) | b);
            }
        }
    }
    
    /**
     * 优化的快速肤色检测算法
     */
    private static boolean isSkinPixelFast(int r, int g, int b) {
        // 改进的RGB肤色检测 - 更精确地识别肤色区域，避免错误检测
        boolean basicCheck = r > 95 && g > 40 && b > 20;
        boolean colorRatioCheck = r > g && r > b && Math.abs(r - g) > 15;
        boolean colorDifferenceCheck = (Math.max(r, Math.max(g, b)) - Math.min(r, Math.min(g, b))) > 15;
        boolean notTooRed = r < 230 || (r - g) < 40 || (r - b) < 40; // 避免将过红的区域识别为肤色
        
        // YCbCr肤色范围检测 - 更严格的范围
        int y = (int)(0.299 * r + 0.587 * g + 0.114 * b);
        int cr = (int)(r - y + 128);
        int cb = (int)(b - y + 128);
        boolean ycbcrCheck = (cr >= 135 && cr <= 165 && cb >= 80 && cb <= 120); // 缩小范围提高精度
        
        return basicCheck && colorRatioCheck && colorDifferenceCheck && notTooRed && ycbcrCheck;
    }
}